package ace.tool.generate.code.impl.resolver.scheme.resolver.api;

import ace.tool.generate.code.impl.manager.common.EntityModelManager;
import ace.tool.generate.code.impl.resolver.scheme.model.bo.api.EnumClassFieldInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.bo.api.EnumClassInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.dto.ClassFileInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.dto.CommonInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.dto.ProjectInfo;
import ace.tool.generate.code.impl.resolver.scheme.resolver.ClassFileInfoResolver;
import ace.tool.generate.code.impl.service.model.input.*;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
import org.apache.commons.text.WordUtils;

/**
 * @author caspar
 * @date 2023/11/17 10:34
 */
@Builder
@RequiredArgsConstructor
public class EnumClassInfoResolver {
  private final GenerateInput input;
  private final GenerateModelInput modelInput;
  private final GenerateModelFieldInput modelFieldInput;
  private final CommonInfo commonInfo;
  private final ProjectInfo apiProjectInfo;

  public EnumClassInfo resolve() {
    EntityModelManager entityModelManager = new EntityModelManager();
    String enumId = entityModelManager.getEnumId(modelInput, modelFieldInput);
    ClassFileInfo classFileInfo =
        ClassFileInfoResolver.builder()
            .className(modelInput.getName())
            .classNameSuffix(WordUtils.capitalize(modelFieldInput.getName()) + "Enum")
            .classPackagePrefix(input.getEnumClassPackagePrefix())
            .rootPackageFullName(commonInfo.getRootPackageFullName())
            .sourceCodeRootDir(apiProjectInfo.getSourceCodeRootDir())
            .build()
            .resolve();

    return EnumClassInfo.builder()
        .enumId(enumId)
        .info(classFileInfo)
        .remark(modelInput.getRemark() + " " + modelFieldInput.getRemark())
        .codeClass(modelFieldInput.getType().getSimpleName())
        .fields(this.getFields())
        .build();
  }

  private List<EnumClassFieldInfo> getFields() {
    return modelFieldInput.getEnums().getFields().stream()
        .map(this::getField)
        .collect(Collectors.toList());
  }

  private EnumClassFieldInfo getField(GenerateEnumFieldInput enumFieldInput) {
    String enumClassFieldInfoCode = this.getEnumClassFieldInfoCode(enumFieldInput);
    return EnumClassFieldInfo.builder()
        .code(enumClassFieldInfoCode)
        .desc(enumFieldInput.getDesc())
        .key(enumFieldInput.getKey())
        .build();
  }

  private String getEnumClassFieldInfoCode(GenerateEnumFieldInput enumFieldInput) {
    if (this.modelFieldInput.getType().equals(String.class)) {
      return String.format("\"%s\"", enumFieldInput.getCode());
    }
    return enumFieldInput.getCode();
  }
}
